<?php

declare(ENCODING = 'UTF-8');

/*                                                                        *
 * This script is part of the TYPO3 project - inspiring people to share!  *
 *                                                                        *
 * TYPO3 is free software; you can redistribute it and/or modify it under *
 * the terms of the GNU General Public License version 2 as published by  *
 * the Free Software Foundation.                                          *
 *                                                                        *
 * This script is distributed in the hope that it will be useful, but     *
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN-    *	
 * TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General      *
 * Public License for more details.                                       *
 *                                                                        */	

/**
 * @package auxo
 * @subpackage core
 * @version $Id$
 */

/**	
 * Configuration 
 * 
 * This class represents a TYPO3 configuration.
 * 
 * @package auxo
 * @subpackage core	
 * @version $Id$	
 * @copyright Copyright belongs to the respective authors
 * @author andreas.horn@extronaut.de
 * @license http://opensource.org/licenses/gpl-license.php GNU Public License, version 2
 */
 class tx_auxo_Configuration {

 	protected $configuration = array();
 	
 	protected $lock = false;
 	
	public function __construct(array $configuration) {
		$this->setT3Configuration($configuration);
	}
	
	/**
	 * Sets a TYPO3 Configuration that usually is passed to an extension via 
	 * method main().
	 *
	 * @param array $configuration a configuration array
	 */
	public function setT3Configuration($configuration) {
		if(is_array($configuration['configurations.'])) {
			$this->configuration = $configuration['configurations.'];
		}	
	}
	
	/**
	 * Set lock flag in order to prevent runtime changes of the configuration
	 *
	 * @param unknown_type $lock
	 */
	public function setLock($lock) {
		$this->lock = $lock;
	}
	
	/**
	 * Returns a configuration value using a query path
	 *
	 * @param string $path path to configuration value
	 * @param midex $default a default value if no configuration is found
	 * @return mixed $value either an array of values or a plain value
	 * @see getValueByPath
	 */
	public function get($path, $default = NULL) {
		if (! ($result = $this->getValueByPath($this->configuration, $path))) {
			return $default;
		}
		
		return $result;
	}
	
	/**
	 * Sets a configuration value using a path
	 * 
	 * @param string $path path to configuration value
	 * @param mixed $value a plain value
	 */
	public function set($path, $value) {
		if (! $this->lock) {
			$this->setValueByPath($this->configuration, $path, $value);
		}
	}
	
	/**
	 * Gets configuration value(s) using a path
	 * 
	 * A path is described like :
	 * <code>
	 * section.subsection.value
	 * 
	 * or if you want to get an array
	 * 
	 * section.subsection.
	 * </code>
	 *
	 * @param array $data data as array
	 * @param string $path path to data 
	 * @return mixed $value either an array of values or a plain value
	 */
	protected function getValueByPath(array $data, $path) {
		$pathArray = explode('.', trim($path));
		$parts = count($pathArray);
		
		for($i = 0; $i < $parts; $i++) {
			if ($i < $parts - 1 ) {
				$data = $data[$pathArray[$i] . '.'];
			} elseif (empty($pathArray[$i])) {
				// It ends with a dot. We return the rest of the array
				return $data;
			} else {
				// It endes without a dot. We return the value.
				return $data[$pathArray[$i]];
			}
		}		
	}
	
	/**
	 * Sets a value using a path to this configuration
	 *
	 * @param array $data
	 * @param string $path
	 * @param mixed $value
	 * @throws tx_auxo_ConfigurationException 
	 */
	protected function setValueByPath(array $data, $path, $value) {
		$pathArray = explode('.', trim($path));
		$parts = count($pathArray);
		$tree = array();
		$pointer = & $this->configuration;
		
		for($i = 0; $i < $parts; $i++) {
			$segment = $pathArray[$i];
			// if last segment?
			if ($i != $parts - 1) {
				$segment .= '.';
				// extend tree with a new dimension
				if (! isset($pointer[$segment])) {
					$pointer[$segment] = array();
				}
				// move to next dimension
				$pointer = & $pointer[$segment];
			}
			else {
				// set value at last segement
				$pointer[$segment] = $value;				
			}
		}
	}
}
?>